package com.example.shkjdemo.camera1

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.*
import android.hardware.Camera
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.common.commonlibrary.utils.FileUtils
import com.common.commonlibrary.utils.TimeUtils
import com.example.shkjdemo.R
import com.example.shkjdemo.databinding.ActivityCamera1Binding
import com.orhanobut.logger.Logger
import java.io.*


class Camera1Activity : AppCompatActivity(), SurfaceHolder.Callback {
    private val TAG = "Camera1Activity"
    lateinit var binding: ActivityCamera1Binding
    var mCamera: Camera? = null
    var mParameters: Camera.Parameters? = null
    lateinit var surfaceView: SurfaceView
    lateinit var mSurfaceHolder: SurfaceHolder
    /**  是否有预览*/
    private var mIsSafeToTakePicture = false

    init {

    }

    private fun initCamera() {
        Thread(Runnable {
            //        打开前置摄像头
            mCamera = try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                        requestPermissions(arrayOf(Manifest.permission.CAMERA), 1)
                    }
                }
//                Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK)
                Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
            } catch (e: RuntimeException) {
                Log.e(TAG, "摄像头打开失败", e)
                null
            }

        }).start()

    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_camera1)
        surfaceView = binding.svImg
        listener()
    }

    private fun listener() {
        binding.btnPhoto.setOnClickListener {
            if (mCamera == null) {
                return@setOnClickListener
            }
            openCamera()
        }

        binding.btnTakePhoto.setOnClickListener {
            if (mCamera == null) {
                return@setOnClickListener
            }
            takePhoto()
        }

        binding.seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {

            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {

            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                if (mCamera == null) {
                    return
                }
                mCamera!!.stopPreview()
                when (seekBar?.progress) {
                    1 -> {
//        设置显示方向
                        mCamera!!.setDisplayOrientation(0)
                    }
                    2 -> {
                        mCamera!!.setDisplayOrientation(90)
                    }
                    3 -> {
                        mCamera!!.setDisplayOrientation(180)
                    }
                    4 -> {
                        mCamera!!.setDisplayOrientation(270)
                    }

                }
                mCamera!!.startPreview()
            }


        })

    }

    private fun takePhoto() {
        if (mIsSafeToTakePicture){
            mCamera?.takePicture({
                ////按下快门瞬间的操作
                Logger.i("$TAG onShutter>>>")
                mIsSafeToTakePicture = false
            }, { data, camera ->
                ////是否保存原始图片的信息
                Logger.i("$TAG takePhoto 是否保存原始图片的信息 $data")

            }, { data, camera ->
                //获取图片
                Logger.i("$TAG takePhoto 获取图片 $data")
                val previewSize = camera?.parameters?.previewSize
                if (data != null) {
                    try {
                        val bitmap = nv21ToBitmap(
                            data,
                            previewSize!!.width,
                            previewSize.height
                        )
                        saveBitmapFile(bitmap)
                    } catch (e: Exception) {
                        Logger.e(TAG + "onPictureTaken>>>", e.message)
                    }
                }
            })
        }
    }


    private fun openCamera() {
//        摄像头参数设置
        mParameters = mCamera!!.parameters
//        旋转
//        mParameters!!.setRotation(180)
//        设置录音提示
//        mParameters!!.setRecordingHint(true)
//        设置帧率 每秒30帧
//        mParameters!!.previewFrameRate = 30
        println("$TAG 获取帧率..." + mParameters!!.previewFrameRate)

        println("$TAG 获取数据的格式1..." + mParameters!!.pictureFormat)
        val a = mParameters!!.pictureFormat
        binding.tvBefore.text = "pictureFormat1:->$a"
//         //设置获取数据的格式
        mParameters!!.pictureFormat = ImageFormat.NV21

        val b = mParameters!!.pictureFormat

        binding.tvAfter.text = "pictureFormat2:->$b"

        println("$TAG 获取数据的格式2..." + mParameters!!.pictureFormat)
        mSurfaceHolder = surfaceView.holder
        mSurfaceHolder.addCallback(this)

        if (mCamera != null) {
            mCamera?.cancelAutoFocus()
            mParameters?.focusMode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE
            mCamera?.autoFocus { success, camera ->
                if (success) {
                    Logger.i(TAG, "对焦成功")
                } else {
                    Logger.i(TAG, "对焦失败")
                }
            }
            mCamera!!.setPreviewDisplay(mSurfaceHolder)
//        设置显示方向
            mCamera!!.setDisplayOrientation(90)
        }

//        setPreviewCallbackWithBuffer 类似setPreiewCallback，一般配合setPreviewCallback使用
//                setPreviewCallbackWithBuffer (Camera.PreviewCallback cb) 要求指定一个字节数组作为缓冲区，
//                用于预览帧数据，这样能够更好的管理预览帧数据时使用的内存。


//        setPreviewCallbackWithBuffer需要在startPreview()之前调用，因为setPreviewCallbackWithBuffer使用时需要指定一个字节数组作为缓冲区，
//        用于预览帧数据，所以我们需要在setPreviewCallbackWithBuffer之前调用addCallbackBuffer，这样onPreviewFrame的data才有值。
//        然后需要在onPreviewFrame中调用，如果在onPreviewFrame中不调用，那么预览帧数据就不会回调给onPreviewFrame。


        mCamera!!.setPreviewCallback { data, camera ->
            //            val previewSize = camera.parameters.previewSize
//            val bitmap = nv21ToBitmap(data, previewSize.width, previewSize.height)
//            binding.ivPreview.setImageBitmap(bitmap)
        }

        mCamera!!.parameters = mParameters
//        开始预览

        mCamera!!.startPreview()
        mIsSafeToTakePicture = true
    }

    private fun nv21ToBitmap(data: ByteArray, width: Int, height: Int): Bitmap {
        Logger.i("$TAG previewSize>>> width = ${width},height = ${height}")
        var imageByte: ByteArray
        var bitmap: Bitmap
        var newOpts = BitmapFactory.Options()
        var options = BitmapFactory.Options()
        newOpts.inJustDecodeBounds = true

        var yuvImage =
            YuvImage(data, ImageFormat.NV21, width, height, null)
        var baos = ByteArrayOutputStream()

        yuvImage.compressToJpeg(
            Rect(0, 0, width, height),
            100,
            baos
        );// 80--JPG图片的质量[0-100],100最高
        imageByte = baos.toByteArray()
        //将imageByte转换成bitmap
        newOpts.inPreferredConfig = Bitmap.Config.RGB_565
        bitmap = BitmapFactory.decodeByteArray(imageByte, 0, imageByte.size, options);
        return bitmap
    }


    override fun onStart() {
        super.onStart()
        initCamera()
    }

    override fun onStop() {
        super.onStop()
        if (mCamera != null) {
            mCamera!!.stopPreview()
            mCamera!!.release()
            mCamera = null
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        if (mCamera != null) {
            mCamera!!.stopPreview()
            mCamera!!.release()
            mCamera = null
        }
    }

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {

    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        holder.removeCallback(this)
        mCamera!!.setPreviewCallback(null)
        mCamera!!.stopPreview()
        mCamera!!.lock()
        mCamera!!.release()
        mCamera = null
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {

    }

    var i = 0
    private fun saveBitmapFile(bitmap: Bitmap) {
        i++
        val picName = TimeUtils.formatDate(System.currentTimeMillis(), "yyyyMMddHHmmss")
        FileUtils.createFileToSave(FileUtils.PATH_PICTURE)
        val filename = FileUtils.PATH_PICTURE + "/test=" + i + "=${picName}.jpg"
        val file = File(filename)//将要保存图片的路径

        try {
            val bos = BufferedOutputStream(FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush()
            bos.close()
        } catch (e: IOException) {
            e.printStackTrace()
            Logger.e("saveBitmapFile>>> e = $e")
        }
    }

}
